home *** CD-ROM | disk | FTP | other *** search
- /* bc.c, code building function of as68 assembler
- *
- * (C) Copyright 1982 Steve Passe
- * All Rights Reserved
- *
- * version 1.00
- * created 10/21/82
- *
- * version 1.01
- *
- * 8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
- * 10/12/87 split into root, pass1 and pass2 parts for overlay on pdp-11
- */
-
- /* begincode */
-
- /* includes */
-
- #include <stdio.h>
- #include "as68.h"
-
- /* externals */
-
- extern char pass; /* present pass number, 1 or 2 */
- extern unsigned line_count; /* line number of source file */
- extern long loc_counter; /* address to assemble obj code */
- extern int loc_plus; /* increment to loc counter */
- extern FLAG abs_long; /* default to absolute long add.*/
- extern FLAG rorg; /* in pc relative mode */
- extern char label[32]; /* buffer for label from preparse */
- extern char instr[33]; /* buffer for mnem, psdo or macro */
-
- extern struct _mtable mtable[]; /* mnemonic lookup table */
- extern struct _mvalue mvalue[]; /* mnemonic code table */
- extern struct _oprnd op1, op2; /* structs to hold operand val */
- extern char code[]; /* code array */
-
- match(mt)
- register struct _mtable *mt;
- {
- register int index; /* index to mvalue */
- int type1 = _none, type2 = _none; /* operand types */
-
- op_clear(&op1);
- op_clear(&op2);
- if (mt->_nops >= 1 && (type1 = op_eval(&op1)) < 0) { /* legal type found? */
- err_out(BAD_OP1); /* first op bad */
- }
- if (mt->_nops == 2 && (type2 = op_eval(&op2)) < 0) { /* second op? */
- err_out(BAD_OP2); /* no good */
- }
- if (type1 < 0 || type2 < 0) {
- return ERROR; /* use NULL opcode */
- }
- if ((index = type_search(mt, type1, type2)) <=0) {
- switch (index) {
- case ILGL_OP1:
- err_out(ILGL_OP1); /* no good */
- return ERROR;
- case ILGL_OP2:
- err_out(ILGL_OP2); /* no good */
- return ERROR;
- default:
- return ERROR;
- }
- }
- return index;
- }
-
- type_search(mt, type1, type2)
- struct _mtable *mt;
- int type1;
- int type2;
- {
- register int x, y; /* count and index */
- register int t1, t2; /* temp for array value */
-
- for (x = mt->_mvc, y = mt->_mvi; x; --x, ++y) { /* search */
- /* find op1 match... */
- if (((t1 = mvalue[y]._optyp1) == type1) /* if exact match */
- || ((!(t1 & ~0xf0)) && (t1 & type1))) { /* or classtyp and match */
- /* search for second match */
- for ( ; (mvalue[y]._optyp1 == t1) && x; --x, ++y) {
- if (((t2 = mvalue[y]._optyp2) == type2) /* 2nd matches */
- || ((!(t2 & ~0xf0)) && (t2 & type2))) { /* or typ & match */
- return y; /* found a match */
- }
- }
- return ILGL_OP2;
- }
- }
- return ILGL_OP1;
- }
-
- /* mask 3 bit immediate data from op1 over bits 3-1 of code [0] */
-
- bbb(op)
- register struct _oprnd *op;
- {
- if (op->_data & ~7) return ERR_BBB;
- code[0] |= (op->_data << 1);
- return NULL;
- }
-
- /* first ext word holds bit number (7/31) from first operand */
-
- bbbx(size, op)
- int size;
- struct _oprnd *op;
- {
- switch (size) {
- case 3:
- if (op->_data & ~7L) return ERR_BX3; /* range? */
- case 5:
- if (op->_data & ~31L) return ERR_BX5;
- code[3] = op->_data;
- return 1; /* 1 ext word */
- default:
- return ERR_BX;
- }
- }
-
- /** mask bits 3-1 of first byte with op1, 8 = 00 */
-
- ccc(op)
- register struct _oprnd *op;
- {
- if (op->_data < 1L || op->_data > 8L) return ERR_CCC;
- code[0] |= (op->_data << 1) & 0x0f;
- /** if (op->_data != 8L) code[0] |= op->_data << 1; **/
-
- return NULL; /* no words added */
- }
-
- /* mask bits 3-1 of first byte, or bits 2-0 of second, with op reg */
-
- rsd(byt, op)
- int byt;
- register struct _oprnd *op;
- {
- code[byt] |= (byt) ? op->_reg : op->_reg << 1;
- return NULL;
- }
-
- /* register mask list from op into ext */
-
- mmkk(order, op)
- char order;
- register struct _oprnd *op;
- {
- register int x;
- unsigned u1 = 0;
- unsigned m1 = 0x0001;
- unsigned m2 = 0x8000;
-
- switch (order) {
- case '>':
- code[2] = op->_reg_list >> 8; /* high byte */
- code[3] = op->_reg_list; /* low byte */
- return 1;
- case '<':
-
- for (x = 15; x >= 0; --x) {
- u1 |= (op->_reg_list & (m1 << x)) ? (m2 >> x) : 0;
- }
-
- code[2] = u1 >> 8; /* high byte */
- code[3] = u1; /* low byte */
- return 1;
- default:
- return ERR_MK;
- }
- }
-
- /* combined e, f, g, h, and j routines, 12/4/82 */
-
- efghj(arg, i, op)
- register char arg;
- register int i;
- register struct _oprnd *op;
- {
- int len, displ;
-
- switch (op->_typ) {
- case _ani: /* (an) */
- if (arg == 'g') {
- code[0] |= (op->_reg << 1);
- code[1] |= 0x80;
- }
- else {
- code[1] |= (0x10 | op->_reg);
- }
- return NULL;
- case _pd_ani: /* -(an) */
- switch (arg) {
- case 'g':
- code[0] |= (0x01 | op->_reg << 1);
- return NULL;
- case 'j': return ERR_J;
- case 'h': return ERR_H;
- default:
- code[1] |= (0x20 | op->_reg);
- return NULL;
- }
-
- case _ani_pi: /* (an)+ */
- switch (arg) {
- case 'g':
- code[0] |= (op->_reg << 1);
- code[1] |= 0xc0;
- return NULL;
- case 'j': return ERR_J;
- case 'h': return ERR_H;
- default:
- code[1] |= (0x18 | op->_reg);
- return NULL;
- }
-
- case _d16_ani: /* d16(an) */
- switch (arg) {
- case 'e':
- case 'j':
- if (/**rorg**/ op->_rel_lbl) {
- op->_ireg = op->_reg; /* reg is an index */
- op->_iregtyp = op->_regtyp; /* move type */
- op->_displ -= (loc_counter + 2); /* make pc relative */
- code[1] |= 0x3b;
- return _d8_i(i, op); /* indexed label */
- }
- break;
- case 'g':
- code[0] |= (0x01 | op->_reg << 1);
- code[1] |= 0x40;
- return _d16(i, op);
- }
- code[1] |= (0x28 | op->_reg);
- return _d16(i, op);
-
- case _d8_anx: /* d8(an,i) */
- if (arg == 'g') {
- code[0] |= (0x01 | op->_reg << 1);
- code[1] |= 0x80;
- }
- else {
- code[1] |= (0x30 | op->_reg);
- }
- return _d8_i(i, op);
-
- case _address: /* abs. add., short or long, or label if _rel_lbl */
- switch (arg) {
- case 'e':
- case 'j':
- if (/**rorg**/ op->_rel_lbl) {
- code[1] |= 0x3a;
- op->_displ = op->_addr - (loc_counter + 2); /* rel. to pc */
- return _d16(i, op); /* finish as 'label' */
- }
- break;
- case 'g':
- code[1] |= 0xc0;
- if (op->_long_val) {
- code[0] |= 0x03;
- code[i++] = op->_addr >> 24;
- code[i++] = op->_addr >> 16;
- len = 2;
- }
- else {
- code[0] |= (0x01);
- len = 1;
- }
- code[i++] = op->_addr >> 8;
- code[i] = op->_addr;
- return len;
- }
- if (op->_long_val) {
- code[1] |= (0x39);
- code[i++] = op->_addr >> 24;
- code[i++] = op->_addr >> 16;
- len = 2;
- }
- else {
- code[1] |= (0x38);
- len = 1;
- }
- code[i++] = op->_addr >> 8;
- code[i] = op->_addr;
- return len;
-
- case _label: /* relative label */
- switch (arg) {
- case 'g': return ERR_G;
- case 'f': return ERR_F;
- case 'h': return ERR_H;
- default:
- code[1] |= 0x3a;
- op->_displ -= (loc_counter + 2); /* rel. to pc */
- return _d16(i, op);
- }
-
- case _labeli: /* label(i) */
- switch (arg) {
- case 'g': return ERR_G;
- case 'f': return ERR_F;
- case 'h': return ERR_H;
- default:
- code[1] |= 0x3b;
- op->_displ -= (loc_counter + 2); /* rel. to pc */
- return _d8_i(i, op);
- }
-
- default:
- return ERR_EFGHJ;
- }
- }
-
- _d16(i, op)
- register int i;
- register struct _oprnd *op;
- {
- if ((op->_displ > 32767) || (op->_displ < -32768)) return ERR_D16;
- code[i] = op->_displ >> 8; /* displacement... */
- code[i+1] = op->_displ; /* ...into ext */
- return 1; /* 1 ext word returned */
- }
-
- _d8_i(i, op)
- register int i;
- register struct _oprnd *op;
- {
- if ((op->_displ > 127) || (op->_displ < -128)) return ERR_D8I;
- if (op->_iregtyp == 'a') code[i] |= 0x80; /* index is addr reg */
- code[i] |= (op->_ireg << 4); /* add index reg # */
- if (op->_inxl) code[i] |= 0x08; /* mark long index size */
- code[i+1] = op->_displ; /* 8 bit displacement */
- return 1;
- }
-
- /* 8/16 bit address displacement */
-
- xxxx(size, op)
- register int size;
- register struct _oprnd *op;
- {
- register int displ;
-
- switch (op->_typ) {
- case _address: /* absolute address */
- displ = op->_addr - (loc_counter + 2); /* make relative to pc */
- break;
- case _label: /* relative address */
- displ = op->_displ;
- break;
- default: /* somethings wrong... */
- return ERR_XXX;
- }
- switch (size) {
- case 8:
- if (displ > 127 || displ < -128) return ERR_XX; /* check range */
- code[1] |= displ; /* put into array */
- return NULL; /* no ext word */
- case 16:
- if (displ > 32766 || displ < -32768) return ERR_XXXX; /* range */
- code[2] = displ >> 8;
- code[3] = displ;
- return 1; /* 1 ext word returned */
- default:
- return ERR_XXX;
- }
- }
-
- /** */
-
- yy(op)
- register struct _oprnd *op;
- {
- if (op->_data > 255L || op->_data < -128L) return ERR_Y;
- code[1] = op->_data;
- return NULL; /* no ext word */
- }
-
- oyz(size, op)
- int size;
- register struct _oprnd *op;
- {
- switch (size) {
- case 8:
- if (op->_data > 255L || op->_data < -128L) return ERR_OY;
- code[3] = op->_data;
- return 1; /* one ext word added */
- case 16:
- if (op->_data > 65535L || op->_data < -32768L) return ERR_YY;
- code[2] = op->_data >> 8;
- code[3] = op->_data;
- return 1; /* one ext word added */
- case 32:
- code[2] = op->_data >> 24;
- code[3] = op->_data >> 16;
- code[4] = op->_data >> 8;
- code[5] = op->_data;
- return 2;
- default:
- return ERR_OYZ;
- }
- }
-
- /*
- byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7 byte 8 byte 9 byte 10
- */
-
- /* none none */
-
- nn()
- {
- return NULL; /* no action required */
- }
-
- /* none none zero yy */
-
- nnoy()
- {
- return oyz(8, &op1); /* 8 bits imd data */
- }
-
- /* none none yyyy */
-
- nnyy()
- {
- return oyz(16, &op1); /* 16 bits imd data */
- }
-
- /* none xx */
-
- nx()
- {
- return xxxx(8, &op1); /* 16 bit displ from op1 */
- }
-
- /* none none xxxx */
-
- nnxx()
- {
- return xxxx(16, &op1); /* 16 bit displ from op1 */
- }
-
- /* none ddd */
-
- nd()
- {
- return rsd(1, &op1); /* dest reg from op1 into byte 1 */
- }
-
- nd2()
- {
- return rsd(1, &op2); /* dest reg from op2 into byte 1 */
- }
-
- /* none ddd zero bbbbb */
-
- ndob()
- {
- rsd(1, &op2); /* dest reg from op2 into byte 1 */
- return bbbx(5, &op1); /* bit field spec into first ext */
- }
-
- /* none ddd kkkk */
-
- ndkk()
- {
- rsd(1, &op2); /* dest reg from op2 into byte 1 */
- return mmkk('<', &op1); /* reglist from op1 into ext */
- }
-
- /* none ddd zero yy */
-
- ndoy()
- {
- rsd(1, &op2); /* dest reg from op2 into byte 1 */
- return oyz(8, &op1); /* 8 bits imd data */
- }
-
- /* none ddd yyyy */
-
- ndyy()
- {
- rsd(1, &op2); /* dest reg from op2 into byte 1 */
- return oyz(16, &op1); /* 16 bits of immediate data */
- }
-
- /* none ddd yyyy zzzz */
-
- ndyz()
- {
- rsd(1, &op2); /* dest reg from op2 into byte 1 */
- return oyz(32, &op1); /* 32 bits of immediate data */
- }
-
- /* none eeeeee [ext] [ext] */
-
- ne()
- {
- return efghj('e', 2, &op1);
- }
-
- /* none ffffff [ext] [ext] */
-
- nf()
- {
- return efghj('f', 2, &op1);
- }
-
- nf2()
- {
- return efghj('f', 2, &op2);
- }
-
- /* none ffffff zero bbb [ext] [ext] */
-
- nfob()
- {
- bbbx(3, &op1);
- return (efghj('f', 4, &op2) + 1);
- }
-
- /* none ffffff zero yy [ext] [ext] */
-
- nfoy()
- {
- oyz(8, &op1); /* 8 bits imd data */
- return (efghj('f', 4, &op2) + 1); /* op2 destination address */
- }
-
- /* none ffffff yyyy [ext] [ext] */
-
- nfyy()
- {
- oyz(16, &op1); /* 16 bits imd data */
- return (efghj('f', 4, &op2) + 1); /* op2 destination address */
- }
-
- /* none ffffff yyyy zzzz [ext] [ext] */
-
- nfyz()
- {
- oyz(32, &op1); /* 32 bits imd data */
- return (efghj('f', 6, &op2) + 2); /* op2 destination address */
- }
-
- /* none hhhhhh mmmm [ext] [ext] */
-
- nhmm()
- {
- mmkk('>', &op1); /* reglist from op1 into ext */
- return (efghj('h', 4, &op2) + 1); /* op2 destination address */
- }
-
- /* none jjjjjj [ext] [ext] */
-
- nj()
- {
- return efghj('j', 2, &op1);
- }
-
- /* none jjjjjj mmmm [ext] [ext] */
-
- njmm()
- {
- mmkk('>', &op2); /* reglist from op2 into ext */
- return (efghj('j', 4, &op1) + 1);
- }
-
- /* none rrr */
-
- nr()
- {
- return rsd(1, &op1); /* source reg from op1 into byte 1 */
- }
-
- nr2()
- {
- return rsd(1, &op2); /* source reg from op2 into byte 1 */
- }
-
- /* none rrr xxxx */
-
- nrxx()
- {
- rsd(1, &op1); /* source reg from op1 into byte 1 */
- return xxxx(16, &op2); /* 16 bit displ from op1 */
- }
-
- /* none rrr yyyy */
-
- nryy() /* special for LINK.W (aka LINK) instr */
- {
- rsd(1, &op1); /* address reg from op1 to byte1 */
- return oyz(16, &op2); /* 16bit displ to op2 */
- }
-
- /* none sss [same as 'none rrr':nr()] */
-
- /* none sss mmmm */
-
- nsmm()
- {
- rsd(1, &op1); /* source reg from op1 into byte 1 */
- return mmkk('>', &op2); /* reglist from op1 into ext */
- }
-
- /* none vvvv */
-
- nv()
- {
- if (op1._data & ~15l) return ERR_V;
- code[1] |= op1._data;
- return NULL;
- }
-
- /* bbb ddd */
- /* same as ccc ddd (sort of) */
-
- /* bbb ffffff [ext] [ext] */
- /* bbb is a misnomer for these two... */
-
- cf()
- {
- ccc(&op1);
- return efghj('f', 2, &op2);
- }
-
- /* ccc ddd */
-
- cd()
- {
- ccc(&op1);
- return rsd(1, &op2);
- }
- /* ddd none zero yy */
-
- dnoy()
- {
- rsd(0, &op2);
- return oyz(8, &op1); /* 8 bits of immediate data */
- }
-
- /* ddd none yyyy */
-
- dnyy()
- {
- rsd(0, &op2);
- return oyz(16, &op1); /* 16 bits of immediate data */
- }
-
- /* ddd none yyyy zzzz */
-
- dnyz()
- {
- rsd(0, &op2);
- return oyz(32, &op1); /* 32 bits of immediate data */
- }
-
- /* ddd eeeeee [ext] [ext] */
-
- de()
- {
- rsd(0, &op2); /* dest reg from op2 into byte 1 */
- return efghj('e', 2, &op1);
- }
-
- /* ddd jjjjjj [ext] [ext] */
-
- dj()
- {
- rsd(0, &op2);
- return efghj('j', 2, &op1);
- }
-
- /* ddd rrr */
-
- dr()
- {
- rsd(0, &op2);
- return rsd(1, &op1); /* source reg from op1 into byte 1 */
- }
-
- /* ddd sss [same as 'ddd rrr': dr()] */
-
- /* ddd sss xxxx */
-
- dsxx()
- {
- rsd(0, &op2);
- rsd(1, &op1); /* source reg from op1 into byte 1 */
- return xxxx(16, &op1); /* 16 bit displ from op1 */
- }
-
- /* ddd yy */
-
- dy()
- {
- rsd(0, &op2);
- return yy(&op1);
- }
-
- /* gggggg none zero yy [ext] [ext] */
-
- gnoy()
- {
- oyz(8, &op1); /* 8 bits of immediate data */
- return (efghj('g', 4, &op2) + 1);
- }
-
- /* gggggg none yyyy [ext] [ext] */
-
- gnyy()
- {
- oyz(16, &op1); /* 16 bits of immediate data */
- return (efghj('g', 4, &op2) + 1);
- }
-
- /* gggggg none yyyy zzzz [ext] [ext] */
-
- gnyz()
- {
- oyz(32, &op1); /* 32 bits of immediate data */
- return (efghj('g', 6, &op2) + 2);
- }
-
- /* gggggg eeeeee [exts] [exts] [extd] [extd] */
-
- ge()
- {
- int temp;
- temp = efghj('e', 2, &op1);
- return (efghj('g', 2 + (temp * 2), &op2) + temp);
- }
-
- /* gggggg sss [ext] [ext] */
-
- gs()
- {
- rsd(1, &op1);
- return efghj('g', 2, &op2);
- }
-
- /* rrr ddd */
-
- rd()
- {
- rsd(0, &op1);
- return rsd(1, &op2);
- }
-
- /* rrr ffffff [ext] [ext] */
-
- rf()
- {
- rsd(0, &op1);
- return efghj('f', 2, &op2);
- }
-
- /* sss ddd [same as 'rrr ddd': rd()] */
-
- /* sss ddd xxxx */
-
- sdxx()
- {
- rsd(0, &op1); /* source reg from op1 into byte 1 */
- rsd(1, &op2);
- return xxxx(16, &op2); /* 16 bit displ from op2 */
- }
-
- /* sss ffffff [ext] [ext] */
-
- sf()
- {
- rsd(0, &op1); /* source reg from op1 into byte 0 */
- return efghj('f', 2, &op2);
- }
-
- /* endcode */
-
-